package com.qingfeng.medical.controller.admin.auth;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qingfeng.currency.dozer.DozerUtils;
import com.qingfeng.medical.base.controller.BaseController;
import com.qingfeng.medical.base.handler.GeneralAuthException;
import com.qingfeng.medical.base.log.annotation.Log;
import com.qingfeng.medical.base.log.enums.BusinessType;
import com.qingfeng.medical.base.result.Result;
import com.qingfeng.medical.base.result.ResultCodeEnum;
import com.qingfeng.medical.base.utils.MD5;
import com.qingfeng.medical.biz.auth.domain.dto.SysUserQueryDTO;
import com.qingfeng.medical.biz.auth.domain.dto.SysUserSaveDTO;
import com.qingfeng.medical.biz.auth.domain.dto.SysUserUpdateDTO;
import com.qingfeng.medical.biz.auth.domain.entity.SysUser;
import com.qingfeng.medical.biz.auth.service.SysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @author 清风学Java
 * @version 1.0.0
 * @date 2023/4/2
 */
@Api(tags = "医院用户管理")
@RestController
@RequestMapping("/admin/system/sysUser")
@Validated
public class SysUserController extends BaseController {

    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private DozerUtils dozerUtils;

    @Log(title = "医院用户管理", businessType = BusinessType.SELECT, message = "获取用户分页列表")
    @PreAuthorize("hasAuthority('bnt.sysUser.list')")
    @ApiOperation(value = "获取用户分页列表", notes = "获取用户分页列表")
    @GetMapping("/{page}/{limit}")
    public Result<IPage<SysUser>> index(
            @ApiParam(name = "page", value = "当前页码", required = true)
            @PathVariable Long page,
            @ApiParam(name = "limit", value = "每页记录数", required = true)
            @PathVariable Long limit,
            @ApiParam(name = "userQueryVo", value = "查询对象", required = false)
                    SysUserQueryDTO userQueryDTO) {
        IPage<SysUser> pageModel = sysUserService.selectPage(
                new Page<SysUser>(page, limit),
                userQueryDTO
        );
        return Result.ok(pageModel);
    }

    @PreAuthorize("hasAuthority('bnt.sysUser.list')")
    @Log(title = "医院用户管理", businessType = BusinessType.SELECT, message = "根据Id获取用户信息")
    @ApiOperation(value = "根据Id获取用户信息", notes = "根据Id获取用户信息")
    @GetMapping("/get/{id}")
    public Result<SysUser> getById(@PathVariable Long id) {
        SysUser user = sysUserService.getById(id);
        return Result.ok(user);
    }

    @PreAuthorize("hasAuthority('bnt.sysUser.info')")
    @Log(title = "医院用户管理", businessType = BusinessType.SELECT, message = "根据Id获取用户信息")
    @ApiOperation(value = "根据Id获取用户信息", notes = "根据Id获取用户信息")
    @GetMapping("/get")
    public Result<SysUser> getUserInfo() {
        SysUser user = sysUserService.getById(getUserId());
        return Result.ok(user);
    }

    @Log(title = "医院用户管理", businessType = BusinessType.INSERT, message = "保存用户信息")
    @PreAuthorize("hasAuthority('bnt.sysUser.add')")
    @ApiOperation(value = "保存用户信息", notes = "保存用户信息")
    @PostMapping("/save")
    public Result save(@RequestBody @Validated SysUserSaveDTO user) {
        // 判断用户是否已经存在
        checkUser(user.getUsername(), null);

        // 对输入的密码进行MD5加密
        user.setPassword(MD5.encrypt(user.getPassword()));
        sysUserService.save(dozerUtils.map(user, SysUser.class));
        return Result.ok();
    }

    @Log(title = "医院用户管理", businessType = BusinessType.UPDATE, message = "更新用户信息")
    @PreAuthorize("hasAuthority('bnt.sysUser.update')")
    @ApiOperation(value = "更新用户信息", notes = "更新用户信息")
    @PutMapping("/update")
    public Result updateById(@RequestBody @Autowired SysUserUpdateDTO user) {
        checkUser(user.getUsername(), user.getId());

        sysUserService.updateById(dozerUtils.map(user, SysUser.class));
        return Result.ok();
    }

    private void checkUser(String username, Long id) {
        // 判断用户是否已经存在
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUsername, username);
        if (ObjectUtil.isNotNull(id)) {
            // 更新
            wrapper.ne(SysUser::getId, id);
        }
        List<SysUser> sysUserList = sysUserService.list(wrapper);

        if (!CollectionUtils.isEmpty(sysUserList)) {
            throw new GeneralAuthException(ResultCodeEnum.USER_ALREADY_EXISTS);
        }
    }

    @Log(title = "医院用户管理", businessType = BusinessType.DELETE, message = "根据Id删除用户信息")
    @PreAuthorize("hasAuthority('bnt.sysUser.remove')")
    @ApiOperation(value = "根据Id删除用户信息", notes = "根据Id删除用户信息")
    @DeleteMapping("/remove/{id}")
    public Result remove(@PathVariable Long id) {
        sysUserService.removeByUserId(id);
        return Result.ok();
    }

    @Log(title = "医院用户管理", businessType = BusinessType.STATUS, message = "更新用户状态")
    @PreAuthorize("hasAuthority('bnt.sysUser.status')")
    @ApiOperation(value = "更新用户状态", notes = "更新用户状态")
    @GetMapping("/updateStatus/{id}/{status}")
    public Result updateStatus(@PathVariable Long id,
                               @PathVariable Integer status) {
        sysUserService.updateStatus(id, status);
        return Result.ok();
    }

    @ApiOperation(value = "导出医院用户信息模板", notes = "导出医院用户信息模板")
    @GetMapping("/excel/export_user_template")
    @Log(title = "医院用户管理", businessType = BusinessType.EXPORT, message = "导出医院用户信息模板")
    public void exportUserTemplate(HttpServletResponse response) {
        sysUserService.exportUserTemplate(response);
    }

    @ApiOperation(value = "导出医院用户信息", notes = "导出医院用户信息")
    @GetMapping("/excel/export_user")
    @Log(title = "医院用户管理", businessType = BusinessType.EXPORT, message = "导出医院用户信息")
    public void exportUser(HttpServletResponse response) {
        sysUserService.exportUser(response);
    }

    @ApiOperation(value = "导入医院用户信息", notes = "导入医院用户信息")
    @PostMapping("/excel/import_user")
    @Log(title = "医院用户管理", businessType = BusinessType.IMPORT, message = "导入医院用户信息")
    public void importUser(MultipartFile file) {
        sysUserService.importUser(file);
    }
}
